using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Admin.NET.Application.Entity.Business;
using Admin.NET.Application.Service.ModuleCollector.Dto;
using Admin.NET.Core;
using Furion.DependencyInjection;
using Furion.DynamicApiController;
using Furion.FriendlyException;
using Mapster;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
using SqlSugar;

namespace Admin.NET.Application;

/// <summary>
/// 采集器2服务
/// </summary>
[ApiDescriptionSettings(new string[] { "业务应用" }, Order = 100)]
public class ModuleGroupCollectorService : IDynamicApiController, ITransient, IPrivateDependency
{
	private readonly SqlSugarRepository<ModuleCollectorGroup> _rep;

	public ModuleGroupCollectorService(SqlSugarRepository<ModuleCollectorGroup> rep)
	{
		_rep = rep;
	}

	/// <summary>
	/// 分页查询模组分组2
	/// </summary>
	/// <param name="input"></param>
	/// <returns></returns>
	[HttpGet("/moduleGroupCollector/page")]
	public async Task<dynamic> Page([FromQuery] ModuleGroupCollectorInput input)
	{
		ISugarQueryable<ModuleCollectorGroup> query = _rep.Context.Queryable<ModuleCollectorGroup>().WhereIF(!string.IsNullOrWhiteSpace(input.Name), (ModuleCollectorGroup u) => u.Name.Contains(input.Name.Trim()));
		query = query.OrderBuilder(input);
		return await query.ToPagedListAsync(input.Page, input.PageSize);
	}

	/// <summary>
	/// 增加模组分组2
	/// </summary>
	/// <param name="input"></param>
	/// <returns></returns>
	[HttpPost("/moduleGroupCollector/add")]
	public async Task Add(AddModuleGroupCollectorInput input)
	{
		ModuleCollectorGroup entity = input.Adapt<ModuleCollectorGroup>();
		await _rep.InsertAsync(entity);
	}

	/// <summary>
	/// 删除模组分组2
	/// </summary>
	/// <param name="input"></param>
	/// <returns></returns>
	[HttpPost("/moduleGroupCollector/delete")]
	public async Task Delete(DeleteModuleCollectorInput input)
	{
		ModuleCollectorGroup entity = await _rep.GetFirstAsync((ModuleCollectorGroup u) => u.Id == input.Id);
		if (await _rep.Context.Queryable<ModuleCollector>().AnyAsync((ModuleCollector u) => u.ModuleCollectorGroupId == (long?)entity.Id))
		{
			throw Oops.Oh(ErrorCodeEnum.D1007);
		}
		await _rep.DeleteAsync(entity);
	}

	/// <summary>
	/// 更新模组分组2
	/// </summary>
	/// <param name="input"></param>
	/// <returns></returns>
	[HttpPost("/moduleGroupCollector/edit")]
	public async Task Update(UpdateModuleGroupCollectorInput input)
	{
		ModuleCollectorGroup entity = input.Adapt<ModuleCollectorGroup>();
		entity.Version++;
		await _rep.Context.Updateable(entity).UpdateColumns((ModuleCollectorGroup u) => new
		{
			u.Version, u.User, u.Stop, u.Isssl, u.Host, u.Len, u.Name, u.Par, u.Port, u.PublishTopic,
			u.Pwd, u.Rate, u.Remark, u.TimeInterval, u.Type, u.Sm, u.Addr
		}).ExecuteCommandAsync();
	}

	/// <summary>
	/// 获取模组分组2
	/// </summary>
	/// <param name="input"></param>
	/// <returns></returns>
	[HttpGet("/moduleGroupCollector/detail")]
	public async Task<ModuleCollectorGroup> Get([FromQuery] QueryeModuleCollectorInput input)
	{
		return await _rep.GetFirstAsync((ModuleCollectorGroup u) => u.Id == input.Id);
	}

	/// <summary>
	/// 获取模组分组2列表
	/// </summary>
	/// <param name="input"></param>
	/// <returns></returns>
	[HttpGet("/moduleGroupCollector/list")]
	public async Task<dynamic> List([FromQuery] ModuleGroupCollectorInput input)
	{
		return await _rep.AsQueryable().ToListAsync();
	}

	/// <summary>
	/// 配置网关
	/// </summary>
	/// <param name="input"></param>
	/// <returns></returns>
	[HttpPost("/moduleGroupCollector/setting")]
	public async Task<int> Setting([FromBody] ModuleCollectorGroupSettingInput input)
	{
		ModuleCollectorGroup collector = await _rep.GetFirstAsync((ModuleCollectorGroup u) => u.Id == input.Id);
		if (collector == null)
		{
			throw Oops.Bah("网关不存在，请刷新后重试");
		}
		collector.Cmds = input.Cmds;
		collector.Cmds.ForEach(delegate(ModuleCollectorCmd u)
		{
			if (u.T != null)
			{
				u.T = u.T.Trim();
			}
		});
		collector.Version++;
		await _rep.Context.Updateable(collector).UpdateColumns((ModuleCollectorGroup u) => new { u.Cmds, u.Version }).ExecuteCommandAsync();
		return 0;
	}

	/// <summary>
	/// 模组获取初始化配置
	/// </summary>
	/// <param name="code"></param>
	/// <param name="version"></param>
	/// <returns></returns>
	[AllowAnonymous]
	[NonUnify]
	[HttpGet("/api/project/version")]
	public async Task<IActionResult> GetConfig([FromQuery] string code, [FromQuery] int? version)
	{
		try
		{
			ModuleCollector modeldevice = await _rep.Context.Queryable<ModuleCollector>().FirstAsync((ModuleCollector u) => u.Imei == code);
			if (modeldevice == null)
			{
				return new BadPageResult();
			}
			ModuleCollectorGroup module = await _rep.GetFirstAsync((ModuleCollectorGroup u) => (long?)u.Id == modeldevice.ModuleCollectorGroupId);
			if (module == null)
			{
				return new BadPageResult();
			}
			if (!version.HasValue)
			{
				return new BadPageResult();
			}
			if (module.Version <= version && modeldevice.Version >= 0)
			{
				return new BadPageResult();
			}
			if (modeldevice.Version.GetValueOrDefault() == -1)
			{
				modeldevice.Version = -2;
				await _rep.Context.Updateable(modeldevice).UpdateColumns((ModuleCollector u) => new { u.Version }).ExecuteCommandAsync();
			}
			int type = ((modeldevice.ProtocolType == 0 || modeldevice.ProtocolType == 2) ? 1 : 0);
			ModuleGroupConfigDto result = new ModuleGroupConfigDto
			{
				version = module.Version,
				init = AesCryptoUtil.Encrypt(JsonConvert.SerializeObject(new ModuleGroupConfigInit
				{
					protocol = type,
					host = module.Host,
					port = module.Port,
					len = int.Parse(module.Len),
					par = int.Parse(module.Par),
					pwd = module.Pwd,
					rate = module.Rate,
					stop = module.Stop,
					type = int.Parse(module.Type),
					user = module.User,
					time = module.TimeInterval,
					isssl = module.Isssl,
					pub = module.PublishTopic,
					sm = (module.Sm ?? ""),
					a = JsonConvert.SerializeObject(ConvertToReversedAddress(module.Addr))
				}), "*dmwl136624@wlkj")
			};
			if (module.Cmds != null)
			{
				result.cmd = module.Cmds.Select((ModuleCollectorCmd s) => new ModuleGroupConfigCmd
				{
					a = s.A,
					d = s.D,
					o = s.O,
					t = s.T,
					z = s.Z,
					k = s.K
				}).ToList();
			}
			else
			{
				result.cmd = new List<ModuleGroupConfigCmd>();
			}
			return new OkObjectResult(result);
		}
		catch (Exception)
		{
			return new BadPageResult();
		}
	}

	/// <summary>
	/// 模组定时心跳检测
	/// </summary>
	/// <param name="imei"></param>
	/// <param name="version"></param>
	/// <param name="deviceota"></param>
	/// <returns></returns>
	[AllowAnonymous]
	[NonUnify]
	[HttpGet("/heartbeat")]
	public async Task<IActionResult> HeartBeat([FromQuery] string imei, [FromQuery] int? version, [FromQuery] string deviceota, [FromQuery] string iccid, [FromQuery] decimal lng, [FromQuery] decimal lat)
	{
		try
		{
			ModuleCollector module = await (from u in _rep.Context.Queryable<ModuleCollector>()
				where u.Imei == imei
				select u).FirstAsync();
			if (module != null && module.Version.GetValueOrDefault() != -1)
			{
				module.LastOnlineTime = DateTime.Now;
				module.Version = version.Value;
				module.Iccid = iccid;
				module.FirmwareVersion = deviceota;
				module.Longitude = lng;
				module.Latitude = lat;
				await _rep.Context.Updateable(module).UpdateColumns((ModuleCollector u) => new { u.LastOnlineTime, u.Version, u.Latitude, u.Longitude, u.Iccid, u.FirmwareVersion }).ExecuteCommandAsync();
			}
		}
		catch (Exception)
		{
		}
		return new OkResult();
	}

	private List<string> ConvertToReversedAddress(string inputAddress)
	{
		if (string.IsNullOrWhiteSpace(inputAddress))
		{
			return new List<string>();
		}
		string[] splitArray = new string[inputAddress.Length / 2];
		for (int i = 0; i < inputAddress.Length / 2; i++)
		{
			splitArray[i] = inputAddress.Substring(i * 2, 2);
		}
		Array.Reverse(splitArray);
		string output = string.Join("", splitArray);
		return new List<string> { output };
	}

	/// <summary>
	/// 复制分组数据
	/// </summary>
	/// <param name="id"></param>
	/// <returns></returns>
	[HttpPost("/moduleGroupCollector/copy")]
	public async Task CopyGroup([FromQuery] long id)
	{
		ModuleCollectorGroup baseData = await _rep.AsQueryable().FirstAsync((ModuleCollectorGroup u) => u.Id == id);
		if (baseData == null)
		{
			throw Oops.Bah("当前分组数据不存在或已被删除，请刷新页面后重试");
		}
		ModuleCollectorGroup newData = baseData.Adapt<ModuleCollectorGroup>();
		newData.Id = 0L;
		newData.Name += "-复制";
		newData.Version = 1;
		newData.CreateTime = null;
		newData.UpdateTime = null;
		newData.CreateUserId = null;
		newData.CreateUserName = null;
		newData.UpdateUserId = null;
		newData.UpdateUserName = null;
		await _rep.InsertAsync(newData);
	}
}
